﻿using System;
using System.Threading;
using System.Threading.Tasks;

namespace AbpProjectTemplate.Utilities.Theading
{
    //Semaphore可以理解为⼀个资源信号量的容器，initialCount，maximumCount两个参数分别代表初始资源数和最⼤资源数。
    //所谓最⼤资源数maximumCount，是指Semaphore容器中所包含的所有资源的数量。这个最⼤资源数maximumCount中，包括当前可⽤
    //的资源，和当前尚未释放的资源。
    //⽽初始资源数initialCount，是指在程序初始状态时，Semaphore释放出了多少个可以直接被线程使⽤的资源。
    //尚未被释放的资源 = maximumCount - initialCount
    //https://wenku.baidu.com/view/dc5e0a190a12a21614791711cc7931b765ce7b30.html

    public class SemaphoreSlimWrapper : SemaphoreSlim 
    {
        public Guid Id { get; private set; }
        public string Name { get; }
        //public int InitialCount { get; }
        public int MaximumCount { get; }

        public SemaphoreSlimWrapper(string name,int maximumCount) 
            : base(maximumCount)
        {
            this.Id = Guid.NewGuid();
            this.Name = name;
            this.MaximumCount = maximumCount;
            TestLogger.WriteLine($"Created:{this.Id}");
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            TestLogger.WriteLine($"Disposed:{this.Id}");
        }
    }


    //public class SemaphoreSlimWrapper : IDisposable
    //{
    //    public Guid Id { get; private set; }
    //    public string Name { get; }
    //    //public int InitialCount { get; }
    //    public int MaximumCount { get; }
    //    public int CurrentCount => this.Slim.CurrentCount;
    //    public int WaitingCount { get; private set; } = 0;
    //    public SemaphoreSlim Slim { get; }

    //    public SemaphoreSlimWrapper(string name, int maximumCount)
    //    {
    //        this.Slim = new SemaphoreSlim(maximumCount);
    //        this.Id = Guid.NewGuid();
    //        this.Name = name;
    //        this.MaximumCount = maximumCount;
    //        Console.WriteLine($"Init:{this.Id}");
    //    }

    //    private void IncreaseWaitingCount(int num)
    //    {
    //        lock (this)
    //            this.WaitingCount += num;
    //    }

    //    public bool Wait(int timeoutSeconds, CancellationToken cancellationToken = default(CancellationToken))
    //    {
    //        //TestLogger.WriteLine($"Wait:{this.Id}");
    //        this.IncreaseWaitingCount(1);
    //        var b = this.Slim.Wait(timeoutSeconds * 1000, cancellationToken);
    //        this.IncreaseWaitingCount(-1);
    //        return b;
    //    }

    //    public async Task<bool> WaitAsync(int timeoutSeconds, CancellationToken cancellationToken = default(CancellationToken))
    //    {
    //        //TestLogger.WriteLine($"WaitAsync:{this.Id}");
    //        this.IncreaseWaitingCount(1);
    //        var b = await this.Slim.WaitAsync(timeoutSeconds * 1000, cancellationToken);
    //        this.IncreaseWaitingCount(-1);
    //        return b;
    //    }

    //    public void Release()
    //    {
    //        this.Slim.Release();
    //    }

    //    public void Dispose()
    //    {
    //        TestLogger.WriteLine($"Dispose:{this.Id}");
    //        this.Slim.Dispose();
    //    }
    //}
}


